package com.mdd.admin.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mdd.admin.LikeAdminThreadLocal;
import com.mdd.admin.service.IShopWithdrawService;
import com.mdd.admin.validate.ShopWithdrawCreateValidate;
import com.mdd.admin.validate.ShopWithdrawSearchValidate;
import com.mdd.admin.validate.ShopWithdrawUpdateValidate;
import com.mdd.admin.validate.commons.PageValidate;
import com.mdd.admin.vo.ShopWithdrawDetailVo;
import com.mdd.admin.vo.ShopWithdrawListedVo;
import com.mdd.common.core.PageResult;
import com.mdd.common.entity.Shop;
import com.mdd.common.entity.ShopWithdraw;
import com.mdd.common.exception.OperateException;
import com.mdd.common.mapper.ShopMapper;
import com.mdd.common.mapper.ShopWithdrawMapper;
import com.mdd.common.util.ConfigUtils;
import com.mdd.common.util.StringUtils;
import com.mdd.common.util.TimeUtils;

/**
 * 商户提现记录实现类
 * @author DEREK
 */
@Service
public class ShopWithdrawServiceImpl implements IShopWithdrawService {
        
    @Resource
    ShopWithdrawMapper shopWithdrawMapper;
    @Resource
    ShopMapper shopMapper;
    
    /**
     * 商户提现记录列表
     *
     * @author DEREK
     * @param pageValidate 分页参数
     * @param searchValidate 搜索参数
     * @return PageResult<ShopWithdrawListedVo>
     */
    @Override
    public PageResult<ShopWithdrawListedVo> list(PageValidate pageValidate, ShopWithdrawSearchValidate searchValidate) {
        Integer page  = pageValidate.getPageNo();
        Integer limit = pageValidate.getPageSize();

        QueryWrapper<ShopWithdraw> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("id");
        
        Integer shopId = LikeAdminThreadLocal.getShopId();
        if(null != shopId && shopId > 1) {
        	queryWrapper.eq("id", shopId);
        }
        shopWithdrawMapper.setSearch(queryWrapper, searchValidate, new String[]{
            "=:orderSn@order_sn:str",
            "=:shopId@shop_id:int",
            "=:money:str",
            "like:realName@real_name:str",
            "=:bankCard@bank_card:str",
            "=:wechatReceive@wechat_receive:str",
            "=:alipayReceive@alipay_receive:str",
            "=:status:int",
            "=:examineTime@examine_time:long",
            "=:refuseReason@refuse_reason:str",
            "=:extend:str",
        });

        IPage<ShopWithdraw> iPage = shopWithdrawMapper.selectPage(new Page<>(page, limit), queryWrapper);

        List<ShopWithdrawListedVo> list = new LinkedList<>();
        for(ShopWithdraw item : iPage.getRecords()) {
            ShopWithdrawListedVo vo = new ShopWithdrawListedVo();
            BeanUtils.copyProperties(item, vo);
            vo.setCreateTime(TimeUtils.timestampToDate(item.getCreateTime()));
            list.add(vo);
        }

        return PageResult.iPageHandle(iPage.getTotal(), iPage.getCurrent(), iPage.getSize(), list);
    }

    /**
     * 商户提现记录详情
     *
     * @author DEREK
     * @param id 主键参数
     * @return ShopWithdraw
     */
    @Override
    public ShopWithdrawDetailVo detail(Integer id) {
        ShopWithdraw model = shopWithdrawMapper.selectOne(
                new QueryWrapper<ShopWithdraw>()
                    .eq("id", id)
                    .last("limit 1"));

        Assert.notNull(model, "数据不存在");

        ShopWithdrawDetailVo vo = new ShopWithdrawDetailVo();
        BeanUtils.copyProperties(model, vo);
        return vo;
    }

    /**
     * 商户提现记录新增
     *
     * @author DEREK
     * @param createValidate 参数
     */
    @Override
    public void add(ShopWithdrawCreateValidate createValidate) {
    	if(StringUtils.isEmpty(createValidate.getBankCard())
    			&& StringUtils.isEmpty(createValidate.getWechatReceive())
    			&& StringUtils.isEmpty(createValidate.getAlipayReceive())) {
    		throw new OperateException("至少选择一种提现方式");
    	}
    	// 判断最低提现余额
    	Map<String, String> config = ConfigUtils.get("withdraw");
    	BigDecimal bigDecimal = new BigDecimal(config.getOrDefault("shopMinMoney", "10"));
    	if(createValidate.getMoney().compareTo(bigDecimal) < 0) {
    		throw new OperateException("最低提现金额为:"+bigDecimal);
    	}
    	Shop shop = shopMapper.selectById(createValidate.getShopId());
    	Assert.notNull(shop, "商户不存在");
    	BigDecimal totalAmount = shop.getTotalAmount().subtract(shop.getFreezeAmount());
    	if(createValidate.getMoney().compareTo(totalAmount) == 1) {
    		throw new OperateException("余额不足");
    	}
    	shop.setFreezeAmount(shop.getFreezeAmount().add(createValidate.getMoney()));
    	shopMapper.updateById(shop);
    	
    	BigDecimal shopServiceCharge = new BigDecimal(config.getOrDefault("shopServiceCharge", "1"));
    	shopServiceCharge = shopServiceCharge.divide(new BigDecimal("100"));
    	BigDecimal divide = createValidate.getMoney().multiply(shopServiceCharge).setScale(2, RoundingMode.HALF_UP);
        ShopWithdraw model = new ShopWithdraw();
        model.setOrderSn("TX"+TimeUtils.timestampToDate(System.currentTimeMillis()/1000, "yyyyMMddHHmmss"));
        model.setShopId(createValidate.getShopId());
        model.setMoney(createValidate.getMoney().subtract(divide));
        model.setExtend(divide.toPlainString());
        model.setRealName(createValidate.getRealName());
        model.setBankCard(createValidate.getBankCard());
        model.setWechatReceive(createValidate.getWechatReceive());
        model.setAlipayReceive(createValidate.getAlipayReceive());
        model.setStatus(0);
        model.setCreateTime(System.currentTimeMillis() / 1000);
        shopWithdrawMapper.insert(model);
    }

    /**
     * 商户提现记录编辑
     *
     * @author DEREK
     * @param updateValidate 参数
     */
    @Override
    @Transactional
    public void edit(ShopWithdrawUpdateValidate updateValidate) {
    	 ShopWithdraw model = shopWithdrawMapper.selectOne(
                 new QueryWrapper<ShopWithdraw>()
                     .eq("id",  updateValidate.getId())
                     .last("limit 1"));

         Assert.notNull(model, "数据不存在!");
         Shop shop = shopMapper.selectById(updateValidate.getShopId());
     	Assert.notNull(shop, "商户不存在");
         
         if(1 == updateValidate.getStatus()) { // 通过
         	shop.setFreezeAmount(shop.getFreezeAmount().subtract(updateValidate.getMoney().add(new BigDecimal(updateValidate.getExtend()))));
         	shop.setTotalAmount(shop.getTotalAmount().subtract(updateValidate.getMoney().add(new BigDecimal(updateValidate.getExtend()))));
         }else if(2 == updateValidate.getStatus()){// 拒绝
         	if(StringUtils.isEmpty(updateValidate.getRefuseReason())) {
         		throw new OperateException("请输入拒绝理由");
         	}
         	shop.setFreezeAmount(shop.getFreezeAmount().subtract(updateValidate.getMoney().add(new BigDecimal(model.getExtend()))));
         }else {
         	throw new OperateException("状态异常");
         }
         shopMapper.updateById(shop);
         model.setId(updateValidate.getId());
         model.setOrderSn(updateValidate.getOrderSn());
         model.setShopId(updateValidate.getShopId());
         model.setMoney(updateValidate.getMoney());
         model.setRealName(updateValidate.getRealName());
         model.setBankCard(updateValidate.getBankCard());
         model.setWechatReceive(updateValidate.getWechatReceive());
         model.setAlipayReceive(updateValidate.getAlipayReceive());
         model.setStatus(updateValidate.getStatus());
         model.setExamineTime(TimeUtils.timestamp());
         model.setRefuseReason(updateValidate.getRefuseReason());
         model.setExtend(updateValidate.getExtend());
         shopWithdrawMapper.updateById(model);
    }

    /**
     * 商户提现记录删除
     *
     * @author DEREK
     * @param id 主键ID
     */
    @Override
    public void del(Integer id) {
        ShopWithdraw model = shopWithdrawMapper.selectOne(
                new QueryWrapper<ShopWithdraw>()
                    .eq("id", id)
                    .last("limit 1"));

        Assert.notNull(model, "数据不存在!");

        shopWithdrawMapper.delete(new QueryWrapper<ShopWithdraw>().eq("id", id));
    }

}
